﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace GoodroommateComputingPlatform.Tasks
{

    /// <summary>
    /// 任务的委托
    /// </summary>
    /// <param name="globals">注册任务时提供的全局变量</param>
    /// <param name="state">启动任务时提供的状态变量</param>
    /// <returns>任务的返回值</returns>
    public delegate object TaskDelegate(object globals, object state);
    
    /// <summary>
    /// 任务结束时的回掉函数
    /// </summary>
    /// <param name="returnValue">任务的返回值</param>
    /// <param name="excption">执行过程中产生的异常</param>
    public delegate void TaskCallback(object returnValue, Exception excption);

    /// <summary>
    /// 支持进度汇报的任务途中可以调用此委托向任务管理器汇报进度
    /// </summary>
    /// <param name="completedCount">已完成的小单位数</param>
    /// <param name="totalCount">总共的小单位数</param>
    public delegate void TaskProgressReport(long completedUnitsCount, long totalUnitsCount);

    /// <summary>
    /// 支持进度汇报的任务委托
    /// </summary>
    /// <param name="globals">注册任务时提供的全局变量</param>
    /// <param name="state">启动任务时提供的状态变量</param>
    /// <param name="progressReport">使用此委托向任务管理器汇报进度</param>
    /// <returns></returns>
    public delegate object TaskDelegateWithProgressReoprt(object globals, object state, TaskProgressReport progressReport);

    /// <summary>
    /// 简易的任务管理器
    /// </summary>
    public interface ITaskManager
    {
        /// <summary>
        /// 获取服务器的状态信息
        /// </summary>
        /// <returns></returns>
        TaskManagerStatus GetStatus();

        /// <summary>
        /// 注册一个任务
        /// </summary>
        /// <param name="name">任务的名称，名称必须唯一</param>
        /// <param name="action">任务的委托</param>
        /// <param name="globals">任务对应的全局变量</param>
        /// <exception cref="ArgumentException">同名任务已经存在</exception>
        void RegisterTask(string name, TaskDelegate action, object globals);

        /// <summary>
        /// 注册一个支持进度汇报的任务
        /// </summary>
        /// <param name="name">任务的名称，名称必须唯一</param>
        /// <param name="action">任务的委托</param>
        /// <param name="globals">任务对应的全局变量</param>
        /// <exception cref="ArgumentException">同名任务已经存在</exception>
        void RegisterTask(string name, TaskDelegateWithProgressReoprt action, object globals);

        /// <summary>
        /// 获取指定名称的任务是否忙碌
        /// </summary>
        /// <param name="name">任务的名称</param>
        /// <exception cref="ArgumentException">指定的任务不存在</exception>
        /// <returns>任务是否忙碌</returns>
        bool IsBusy(string name);

        /// <summary>
        /// 获取指定名称的任务信息
        /// </summary>
        /// <param name="name">任务的名称</param>
        /// <exception cref="ArgumentException">指定的任务不存在</exception>
        /// <returns>任务信息</returns>
        TaskStatus GetTaskStatus(string name);

        /// <summary>
        /// 获取所有的任务
        /// </summary>
        /// <returns>所有的任务</returns>
        IEnumerable<TaskStatus> GetAllTasks();

        /// <summary>
        /// 启动指定名称的任务，如果任务已经开始，则不做任何操作
        /// </summary>
        /// <param name="name">任务的名称</param>
        /// <param name="state">本次执行的状态变量</param>
        /// <param name="callback">任务执行结束后调用的委托</param>
        /// <exception cref="ArgumentException">指定的任务不存在</exception>
        void StartTaskIfIdle(string name, object state, TaskCallback callback);

        /// <summary>
        /// 启动指定名称的任务，如果任务已经开始，则抛出异常
        /// </summary>
        /// <param name="name">任务的名称</param>
        /// <param name="state">本次执行的状态变量</param>
        /// <param name="callback">任务执行结束后调用的委托</param>
        /// <exception cref="ArgumentException">指定的任务不存在</exception>
        /// <exception cref="InvalidOperationException">指定的任务正在进行中</exception>
        void StartTask(string name, object state, TaskCallback callback);
    }
}
